<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	</body>
	<script>
		//https://blog.csdn.net/qq_37268201/article/details/113175919?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_v2~rank_aggregation-2-113175919.pc_agg_rank_aggregation&utm_term=js+new%E7%9A%84%E8%BF%87%E7%A8%8B%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88&spm=1000.2123.3001.4430
		function Car(year, color, model) {
			this.year = year;
			this.color = color;
			this.model = model;
		}
		Car.prototype.getYear = function(){
			return this.year;
		}
		
		/**
		 *  new 关键字运算过程会进行如下的操作：
			创建一个空的简单JavaScript对象（即{}）；
			链接该对象（设置该对象的constructor）到另一个对象 ；
			将步骤1新创建的对象作为this的上下文 ；
			返回新创建的对象，如果该函数没有返回对象，则返回this。
			接下来我们可以通过手写下面的这段代码来模拟new运算的过程：
		 */
		
		// objectFactory 函数来模拟用 new创建对象
		var objectFactory = function(){
			var obj = new Object(); // 克隆一个空对象； 
			//arguments   https://blog.csdn.net/qq_16339527/article/details/53231725
			Constructor = [].shift.call(arguments); // 获取外部传入的构造器，此例子是Car
			obj.__proto__ = Constructor.prototype; // 指向正确的原型，使得obj.__proto__ 指向 Car.prototype，而不是原来的 Object.prototype。
			var ret = Constructor.apply(obj, arguments); // 借用外部的构造器给obj设置属性
			return typeof ret === 'object' ? ret : obj; // 确保构造器总是返回一个对象
		}
		// 验证
		var car1 = objectFactory(Car, 2020,'red');
		console.log(car1.year); // 输出: 2020
		console.log(car1.getYear()); // 输出: 2020 
		console.log(car1.color); // 
		console.log( Object.getPrototypeOf( car1 ) === Car.prototype ); // 输出: true
	</script>
</html>
